#include "StdAfx.h"
#include "LightShapeRenderNode.h"
#include "VisAreas.h"
#include "ObjMan.h"
#include "CRELightShape.h"

//////////////////////////////////////////////////////////////////////////
CLightShapeRenderNode::CLightShapeRenderNode()
{
	m_bounds.min = Vec3(-1,-1,-1);
	m_bounds.max = Vec3(1,1,1);
	m_matrix.SetIdentity();
	m_pLightShapeRenderElement = (CRELightShape*)GetRenderer()->EF_CreateRE( eDATA_LightShape );
	m_pRenderObject = GetRenderer()->EF_GetObject_Perm();
	m_nLSFlags = 0;
	m_bSerialize = false;
}

//////////////////////////////////////////////////////////////////////////
CLightShapeRenderNode::~CLightShapeRenderNode()
{
	GetRenderer()->EF_ObjRemovePermanent(m_pRenderObject);
	m_pLightShapeRenderElement->Release(false);

	Get3DEngine()->UnRegisterEntity( this );
	Get3DEngine()->FreeRenderNodeState(this);
}

//////////////////////////////////////////////////////////////////////////
float CLightShapeRenderNode::GetMaxViewDist()
{
	if (GetMinSpecFromRenderNodeFlags(m_dwRndFlags) == CONFIG_DETAIL_SPEC)
		return max(GetCVars()->e_ViewDistMin,GetBBox().GetRadius()*GetCVars()->e_ViewDistRatioDetail*GetViewDistRatioNormilized());

	return max(GetCVars()->e_ViewDistMin,GetBBox().GetRadius()*GetCVars()->e_ViewDistRatio*GetViewDistRatioNormilized());
}

//////////////////////////////////////////////////////////////////////////

bool CLightShapeRenderNode::LoadLightBox( )
{
	m_bounds.min = Vec3(0,0,0);
	m_bounds.max = Vec3(1,1,1);

	m_pStatObj = Get3DEngine()->CreateStatObj();
	if ( m_pStatObj )
	{
		if(!Cry3DEngineBase::GetObjManager()->m_pRMBox)
			Cry3DEngineBase::GetObjManager()->MakeUnitCube();
		((CStatObj*)(m_pStatObj.get()))->SetRenderMesh( Cry3DEngineBase::GetObjManager()->m_pRMBox );
		m_bSerialize = true;
		m_dwRndFlags |= ERF_RENDER_ALWAYS;
		m_dwRndFlags &= ~ERF_OUTDOORONLY;
		return true;
	}
	return false;
}

bool CLightShapeRenderNode::LoadLightShape( const char *sLightShapeFilename, const uint32 nLSFlags )
{
	m_bounds.min = Vec3(-1,-1,-1);
	m_bounds.max = Vec3(1,1,1);

	m_nLSFlags = 0;

	if ( sLightShapeFilename[0] == '\0' )
		return false;

	m_pStatObj = Get3DEngine()->LoadStatObj(sLightShapeFilename,NULL,NULL,true,0);
	if ( m_pStatObj )
	{
		m_bounds = m_pStatObj->GetAABB();
		m_nLSFlags = nLSFlags;
		m_dwRndFlags |= ERF_RENDER_ALWAYS;
		m_dwRndFlags &= ~ERF_OUTDOORONLY;
		return true;
	}
	
	return false;
}

//////////////////////////////////////////////////////////////////////////
void CLightShapeRenderNode::SetMatrix( const Matrix34& mat )
{
	m_dwRndFlags |= ERF_RENDER_ALWAYS;
	m_dwRndFlags &= ~ERF_OUTDOORONLY;

	m_matrix = mat;
	m_pos = mat.GetTranslation();
	m_WSBBox.SetTransformedAABB( mat, m_bounds );

	Get3DEngine()->RegisterEntity( this );
}

//////////////////////////////////////////////////////////////////////////
void CLightShapeRenderNode::Render( const SRendParams &rParams )
{
	FUNCTION_PROFILER_3DENGINE;

	if (m_pRenderObject == NULL)
		return;

	if (m_pStatObj == NULL || m_pStatObj->GetRenderMesh() == NULL)
		return;

	if(m_nLSFlags & elsfDisableGI)
	{
		GetRenderer()->Ef_AddDeferredGIClipVolume(m_pStatObj->GetRenderMesh(), m_matrix);
	}
}

//////////////////////////////////////////////////////////////////////////
bool CLightShapeRenderNode::CheckIntersection(const Vec3& p1, const Vec3& p2)
{
	if(p1==p2)
		return false;
	if(m_pStatObj)
	{
		Vec3 outp;
		if(Intersect::Lineseg_AABB(Lineseg(p1, p2), m_WSBBox, outp))
			return true;
	}
	return false;
}

void CLightShapeRenderNode::SetLSFlags( const uint32 nNewFlags )
{
	m_nLSFlags = nNewFlags;
}

void CLightShapeRenderNode::GetLocalBounds( AABB &bbox )
{
	bbox.min = Vec3(0.f, 0.f, 0.f);
	bbox.max = m_WSBBox.max - m_WSBBox.min; 
}

void CLightShapeRenderNode::OffsetPosition(const Vec3& delta)
{
#ifdef SEG_WORLD
	m_matrix.SetTranslation(m_matrix.GetTranslation() + delta);
	m_pos += delta;
	m_WSBBox.Move(delta);
#endif
}

#include UNIQUE_VIRTUAL_WRAPPER(ILightShapeRenderNode)